
#pragma once

#import <msxml6.dll>

#include "FileName.h"
#include "StreamDiffResultStats.h"
#include "StreamDiffResultLineCollection.h"

class XmlDiffResultFormatter
{
public:

	static HRESULT Format(
		__in StreamDiffResultLineCollectionSharedPtr& diffResultLineCollection,
		__in const FileNameW& outputFileName
		);

private:

	//
	// element names
	//
	static PCWSTR m_rootElementName;
	static PCWSTR m_summaryElementName;
	static PCWSTR m_diffLinesElementName;
	static PCWSTR m_diffLineElementName;
	static PCWSTR m_contentElementName;

	//
	// attribute names
	//
    static PCWSTR m_differentAttrName;
	static PCWSTR m_percentageDiffAttrName;
	static PCWSTR m_linesTotalAttrName;
	static PCWSTR m_linesSameAttrName;
	static PCWSTR m_linesAddedAttrName;
	static PCWSTR m_linesRemovedAttrName;
	static PCWSTR m_typeAttrName;
	static PCWSTR m_lineNumberAttrName;
	static PCWSTR m_sourceLineNumberAttrName;
	static PCWSTR m_destinationLineNumberAttrName;

	//
	// value names
	//
	static PCWSTR m_diffTypeCopy;
	static PCWSTR m_diffTypeDelete;
	static PCWSTR m_diffTypeInsert;

	static
    HRESULT
    Write(
        __in StreamDiffResultLineCollection& collection,
        __in const FileNameW& fileName
        );

    struct AttributeNameValue
    {
        PCWSTR m_name;
        const std::wstring& m_value;
        bool m_optional;
    };

	static
    HRESULT
    WriteAttributes(
        __inout MSXML2::IXMLDOMElementPtr& elementNode,
        __in const AttributeNameValue* nameValueArray,
        __in size_t arraySize
        );

	static
    HRESULT
    Write(
        __inout MSXML2::IXMLDOMDocument2Ptr& domDocument,
        __in StreamDiffResultLineCollection& collection
        );

	static
	HRESULT
	Write(
        __inout MSXML2::IXMLDOMDocument2Ptr& domDocument,
		__inout MSXML2::IXMLDOMElementPtr parentNode,
		__in StreamDiffResultStats& summary
		);
           
	static
	HRESULT
	Write(
		__inout MSXML2::IXMLDOMDocument2Ptr& domDocument,
		__inout MSXML2::IXMLDOMElementPtr parentNode,
		__in StreamDiffResultLineCollection& diffResultLineCollection
		);

	static
    HRESULT
    Write(
        __inout MSXML2::IXMLDOMDocument2Ptr& domDocument,
        __inout MSXML2::IXMLDOMElementPtr& parentNode,
        __in SizeType lineIndex,
        __in std::wstring& lineStr,
        __in StreamDiffResult::Type& lineType,
        __in SizeType& oldLineNumber,
        __in SizeType& newLineNumber
        );

	static
    HRESULT
    FormatXmlDocument(
        __in const MSXML2::IXMLDOMDocument2Ptr& inputDocument,
        __inout MSXML2::IXMLDOMDocument2Ptr& formattedDocument
        );

	static
	PCWSTR
	ToString(
		StreamDiffResult::Type type
		)
	{
		PCWSTR typeStr = L"";

		switch (type)
		{
			case StreamDiffResult::Copy:
				typeStr = m_diffTypeCopy;

				break;

			case StreamDiffResult::Delete:
				typeStr = m_diffTypeDelete;

				break;

			case StreamDiffResult::Insert:
				typeStr = m_diffTypeInsert;

				break;

			default:
				break;
		}

		return typeStr;
	}
};